package com.artifex.mupdf.viewer;

import static com.artifex.mupdf.viewer.SettingsItem.TYPE.DIVIDER;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.ENCODE;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.ENGINE;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.FROM;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.HEADER;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.TO;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.fSPEED;
import static com.artifex.mupdf.viewer.SettingsItem.TYPE.tSPEED;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.MenuItem;
import android.widget.ListView;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class TTSSettingsActivity extends AppCompatActivity {
    final static String TAG = TTSSettingsActivity.class.getSimpleName();
    private static final int CHECK_REQUEST_CODE = 1;
    private SettingsAdapter adapter;
    private List<SettingsItem> settingsItems;

    SharedPreferences prefs;

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        super.onCreate(savedInstanceState);

        if (getIntent().getData() == null) {
            Log.e(TAG, "Null");
            return;
        }
        prefs = getSharedPreferences(TTSDocument.base64(getIntent().getDataString()), Context.MODE_PRIVATE);

        setContentView(R.layout.activity_settings);


        // 初始化UI
        initViews();
        setupSettingsList();

        // 设置工具栏
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if(getSupportActionBar()!=null)
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    private void initViews() {
        ListView listView = findViewById(R.id.settings_list);
        settingsItems = new ArrayList<>();
        adapter = new SettingsAdapter(this, settingsItems, this::onSettingsItemClick);
        listView.setAdapter(adapter);
    }

    private void setupSettingsList() {
        settingsItems.clear();

        //编码
        {
            SettingsItem tmp;
            settingsItems.add(new SettingsItem("encode", null, HEADER, ENCODE));
            tmp = new SettingsItem();
            tmp.type = DIVIDER;
            settingsItems.add(tmp);
            tmp = new SettingsItem(null, null, ENCODE, null);
            tmp.encode = "GBK";
            settingsItems.add(tmp);
            tmp = new SettingsItem(null, null, ENCODE, null);
            tmp.encode = "UTF8";
            settingsItems.add(tmp);
        }

        //阅读速度
        {
            settingsItems.add(new SettingsItem(getString(R.string.source_speed), null, HEADER, fSPEED));

            SettingsItem tmp = new SettingsItem();
            tmp.type = DIVIDER;
            tmp.category = fSPEED;
            settingsItems.add(tmp);

            tmp = new SettingsItem(getString(R.string.source_speed), null, fSPEED, null);
            tmp.speed = 1.0f;
            settingsItems.add(tmp);
            tmp = new SettingsItem(getString(R.string.source_speed), null, fSPEED, null);
            tmp.speed = 1.25f;
            settingsItems.add(tmp);
            tmp = new SettingsItem(getString(R.string.source_speed), null, fSPEED, null);
            tmp.speed = 1.5f;
            settingsItems.add(tmp);
            tmp = new SettingsItem(getString(R.string.source_speed), null, fSPEED, null);
            tmp.speed = 1.75f;
            settingsItems.add(tmp);
        }
        //翻译阅读速度
        {
            settingsItems.add(new SettingsItem(getString(R.string.translated_speed), null, HEADER, tSPEED));

            SettingsItem tmp = new SettingsItem();
            tmp.type = DIVIDER;
            tmp.category = tSPEED;
            settingsItems.add(tmp);


            tmp = new SettingsItem(getString(R.string.translated_speed), null, tSPEED, null);
            tmp.speed = 1.0f;
            settingsItems.add(tmp);
            tmp = new SettingsItem(getString(R.string.translated_speed), null, tSPEED, null);
            tmp.speed = 1.25f;
            settingsItems.add(tmp);
            tmp = new SettingsItem(getString(R.string.translated_speed), null, tSPEED, null);
            tmp.speed = 1.5f;
            settingsItems.add(tmp);
            tmp = new SettingsItem(getString(R.string.translated_speed), null, tSPEED, null);
            tmp.speed = 1.75f;
            settingsItems.add(tmp);
        }

        //TTS引擎
        settingsItems.add(new SettingsItem(getString(R.string.engine), null, HEADER, ENGINE));
        Intent intent = new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE);
        PackageManager pm = getPackageManager();
        List<ResolveInfo> resolveInfos = pm.queryIntentServices(intent, PackageManager.MATCH_ALL);

        {
            SettingsItem tmp = new SettingsItem();
            tmp.type = DIVIDER;
            tmp.category = ENGINE;
            settingsItems.add(tmp);
        }

//        List<Task<Void>> tasks = new ArrayList<>();
        for (ResolveInfo info : resolveInfos) {
            if (info.serviceInfo != null) {
                SettingsItem item = new SettingsItem(info.serviceInfo.name, info.serviceInfo.packageName, ENGINE, null);
                settingsItems.add(item);

//                tasks.add(checkTTS(info.serviceInfo.packageName));
            }
        }

        {
            SettingsItem tmp;

            tmp = new SettingsItem();
            tmp.type = HEADER;
            tmp.name = getString(R.string.from_language);
            tmp.category = FROM;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = DIVIDER;
            tmp.category = FROM;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = FROM;
            tmp.language = Locale.ENGLISH;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = FROM;
            tmp.language = Locale.CHINESE;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = FROM;
            tmp.language = Locale.JAPANESE;
            settingsItems.add(tmp);
        }
        {
            SettingsItem tmp;
            tmp = new SettingsItem();
            tmp.type = HEADER;
            tmp.name = getString(R.string.to_language);
            tmp.category = TO;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = DIVIDER;
            tmp.category = TO;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = TO;
            tmp.language = Locale.CHINESE;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = TO;
            tmp.language = Locale.ENGLISH;
            settingsItems.add(tmp);

            tmp = new SettingsItem();
            tmp.type = TO;
            tmp.language = Locale.JAPANESE;
            settingsItems.add(tmp);
        }
//        Tasks.whenAll(tasks).addOnCompleteListener(i -> prefsToList());

        prefsToList();
    }
    void prefsToList() {
        String selectedEngine = prefs.getString(ENGINE.name(), null);
        float selectedFromSpeed = prefs.getFloat(fSPEED.name(), 1.25f);
        float selectedToSpeed = prefs.getFloat(tSPEED.name(), 1.5f);
        String selectedFromLanguage = prefs.getString(FROM.name(), null);
        String selectedToLanguage = prefs.getString(TO.name(), null);
        String selectedEncode = prefs.getString(ENCODE.name(), "UTF8");

//        settingsItems.addAll(hiddenItems);
//        hiddenItems.clear();

        for (SettingsItem i : settingsItems) {
            if (i.type == ENGINE) {
                i.selected = i.packageName.equals(selectedEngine);
            } else if (i.type == fSPEED) {
                i.selected = (i.speed == selectedFromSpeed);
            } else if (i.type == tSPEED) {
                i.selected = (i.speed == selectedToSpeed);
            } else if (i.type == FROM) {
                i.selected = i.language.getLanguage().equals(selectedFromLanguage);
            } else if (i.type == TO) {
                i.selected = i.language.getLanguage().equals(selectedToLanguage);
            } else if (i.type == ENCODE) {
                i.selected = i.encode.equals(selectedEncode);
            }
        }

        adapter.notifyDataSetChanged();
    }

    private void onSettingsItemClick(SettingsItem item, int position) {
        item.selected = true;
        for (SettingsItem i : settingsItems) {
            if (i.type != item.type || i.equals(item)) continue;
            i.selected = false;
        }

        if (ENGINE == item.type) {
            String preEngine = prefs.getString(ENGINE.name(), null);
            if (item.packageName.equals(preEngine))
                return;
            prefs.edit().putString(ENGINE.name(), item.packageName).apply();
        } else if (item.type == fSPEED) {
            prefs.edit().putFloat(fSPEED.name(), item.speed).apply();
        } else if (item.type == tSPEED) {
            prefs.edit().putFloat(tSPEED.name(), item.speed).apply();
        } else if (item.type == FROM) {
            prefs.edit().putString(FROM.name(), item.language.getLanguage()).apply();
        } else if (item.type == TO) {
            prefs.edit().putString(TO.name(), item.language.getLanguage()).apply();
        } else if (item.type == ENCODE) {
            prefs.edit().putString(ENCODE.name(), item.encode).apply();
        }
        adapter.notifyDataSetChanged();
    }

    protected void onCheckTTSResult(String packageName, int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == CHECK_REQUEST_CODE && resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS && data != null) {
            ArrayList<String> voices = data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
            if (voices != null && !voices.isEmpty()) {

                // add voices under specific packageName
                Log.d(TAG, "EXTRA_AVAILABLE_VOICES");
                // 原文语言
                SettingsItem itemFromHeader = new SettingsItem();
                itemFromHeader.type = HEADER;
                itemFromHeader.name = getString(R.string.from_language);
                itemFromHeader.category = FROM;
                itemFromHeader.packageName = packageName;
                settingsItems.add(itemFromHeader);

                List<SettingsItem> fromItems = new ArrayList<>();
                for (String i : voices) {
                    Log.d(TAG, i);
                    String[] tmp = i.split("-");
                    if (tmp.length > 0) {
                        SettingsItem item = new SettingsItem();
                        item.name = i;
                        item.packageName = packageName;
                        item.type = FROM;
                        if (tmp.length == 1) {
                            item.language = new Locale(tmp[0]);
                        } else if (tmp.length == 2) {
                            item.language = new Locale(tmp[0], tmp[1]);
                        } else if (tmp.length == 3) {
                            item.language = new Locale(tmp[0], tmp[1], tmp[2]);
                        }
                        fromItems.add(item);
                    }
                }
                settingsItems.addAll(fromItems);

                //翻译目标语言
                SettingsItem itemToHeader = new SettingsItem();
                itemToHeader.type = HEADER;
                itemToHeader.name = getString(R.string.to_language);
                itemToHeader.category = TO;
                itemToHeader.packageName = packageName;
                settingsItems.add(itemToHeader);
                //重复一次但是类型改成"TO"
                for (SettingsItem i : fromItems) {
                    SettingsItem item = new SettingsItem();
                    item.name = i.name;
                    item.type = TO;
                    item.language = i.language;
                    item.packageName = packageName;
                    settingsItems.add(item);
                }
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}